﻿using System;
using System.Text;

namespace AviationSimulator.UDP
{
    internal class Datagram
    {
        private string _messageBody;
        private Int16 _packageLenght;
        private PackageTypes _packageType;

        public PackageTypes PackageType
        {
            get { return _packageType; }
            set { _packageType = value; }
        }

        public Int16 PackageLenght
        {
            get { return _packageLenght; }
        }

        public string MessageBody
        {
            get { return _messageBody; }
            set
            {
                _messageBody = value;

                _packageLenght = Int16.Parse(_messageBody.Length.ToString());
            }
        }

        public Datagram()
        {
            _packageType = PackageTypes.Undefined;

            MessageBody = String.Empty;
        }

        public Datagram(byte[] datagram)
        {
            InitializeDatagram(datagram);
        }

        public void InitializeDatagram(byte[] datagram)
        {
            if (datagram.Length >= 4)
            {
                try
                {
                    var bType = new[] {datagram[0], datagram[1]};
                    var bLenght = new[] {datagram[2], datagram[3]};

                    Int16 type = BitConverter.ToInt16(bType, 0);


                    _packageType = (PackageTypes) type;

                    switch (_packageType)
                    {
                        case PackageTypes.Info:

                            #region Info package

                            _packageLenght = BitConverter.ToInt16(bLenght, 0);

                            _messageBody = _packageLenght != 0 ? Encoding.ASCII.GetString(datagram, 4, datagram.Length - 4) : String.Empty;

                            #endregion

                            break;

                        case PackageTypes.Ready:
                            break;

                        case PackageTypes.GetData:
                            break;

                        case PackageTypes.SendData:
                            break;

                        case PackageTypes.Undefined:
                            break;

                        default:

                            #region Default

                            _packageType = PackageTypes.Undefined;
                            _packageLenght = 0;
                            _messageBody = "GeneratedBody: UDP datagramm was not correct format.";

                            #endregion

                            break;
                    }

                    #region Old Code

                    //if (packageType != PackageTypes.Ready)
                    //{

                    //    packageLenght = BitConverter.ToInt16(bLenght, 0);

                    //    if (packageLenght != 0)
                    //    {
                    //        messageBody = Encoding.ASCII.GetString(Datagram, 4, Datagram.Length - 4);
                    //    }
                    //    else
                    //    {
                    //        messageBody = String.Empty;
                    //    }

                    //}
                    //else
                    //{
                    //    packageLenght = 0;
                    //    messageBody = String.Empty;
                    //} 

                    #endregion
                }
                catch (IndexOutOfRangeException ioex)
                {
                    throw new IndexOutOfRangeException("Ошибка при инициализации параметров информационного пакета.",
                                                       ioex);
                }
                catch (InvalidCastException icex)
                {
                    throw new InvalidCastException(
                        "Ошибка преобразования типов при инициализации параметров информационного пакета", icex);
                }
                catch (Exception ex)
                {
                    throw new Exception("Ошибка инициализации параметров информационного пакета", ex);
                }
            }
            else
            {
                throw new Exception("Полученный пакет некорректен или поврежден.");
            }
        }

        public override string ToString()
        {
            var result = new StringBuilder();
            result.Append(_packageType.ToString());
            result.Append("|");
            result.Append(_packageLenght.ToString());
            result.Append("|");
            result.Append(_messageBody);

            return result.ToString();
        }

        public byte[] ToByteArray()
        {
            byte[] arrType = BitConverter.GetBytes((Int16) PackageType);

            byte[] arrLenght = BitConverter.GetBytes(_packageLenght);

            byte[] arrMessage = Encoding.ASCII.GetBytes(MessageBody);

            var result = new byte[arrType.Length + arrLenght.Length + arrMessage.Length];

            arrType.CopyTo(result, 0);
            arrLenght.CopyTo(result, arrType.Length);
            arrMessage.CopyTo(result, arrType.Length + arrLenght.Length);

            return result;
        }
    }
}